#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

#define RD 0
#define WR 1

const uint INT_LEN = sizeof(int);

void primes(int lpipe[2])
{
  int temp;
  // printf("Here begin one new circle!");

  int flag;
  // 从左管道读取一个数
  if (read(lpipe[RD], &temp, INT_LEN) == INT_LEN)
  {
    printf("prime %d ", temp);
    flag = 1;
  }
  else
  {
    flag = -1;
  }
  // 如果读到数的话，创建一个新管道，并将除掉后的数加入新管道
  if (flag == 1)
  {
    close(lpipe[WR]);
    // printf("I come here!\n");
    // 创建一个新管道
    int p[2];
    pipe(p);
    // 判断下一个数是否符合要求
    int n;
    while (read(lpipe[RD], &n, INT_LEN) == INT_LEN)
    {
      if (n % temp != 0)
      {
        write(p[WR], &n, INT_LEN);
      }
    }
    printf("\n");
    close(lpipe[RD]);
    close(p[WR]);

    // 子进程中fork() = 0
    if (fork() == 0)
    {
      // printf("I come here!");
      primes(p);
    }
    else
    {
      close(p[RD]);
      wait(0);
    }
  }
}

// 经过测试，发现管道中的缓冲区只有512字节，所以在写入129个数后，
// 进程就会阻塞了，所以如果想要通过管道筛选，就只能限制在129个数以内。
int main(int argc, char const *argv[])
{
  int p[2];
  // 创建管道;
  pipe(p);

  for (int i = 2; i <= 129; i++)
  {
    write(p[WR], &i, INT_LEN);
  }

  // 子进程中fork() == 0
  if (fork() == 0)
  {
    primes(p);
  }
  else
  {
    close(p[RD]);
    close(p[WR]);
    wait(0);
  }

  exit(0);
}
